package river_city_ransom.implementations;

import exceptions.ComposantError;
import river_city_ransom.services.Equipable;
import river_city_ransom.services.Personnage;
import river_city_ransom.services.Position;
import tools.Toolbox;


public abstract class Personnage_I extends Equipable_I implements Personnage {
	protected String nom;
	protected int force;
	protected int maxPointsDeVie;
	protected int pointsDeVie;
	protected boolean estVaincu;
	protected Equipable choseEquipee;
	protected boolean estEquipe;
	protected int estGele;
	protected boolean versLaDroite;
	
	@Override
	public boolean equals(Object o) {
		if(!(o instanceof Personnage)) {
			return false;
		}
		if(!super.equals(o)) {
			return false;
		}
		if(nom() != ((Personnage) o).nom()) {
			return false;
		}
		if(force() != ((Personnage) o).force()) {
			return false;
		}
		if(maxPointsDeVie() != ((Personnage) o).maxPointsDeVie()) {
			return false;
		}
		if(pointsDeVie() != ((Personnage) o).pointsDeVie()) {
			return false;
		}
		if(estVaincu() != ((Personnage) o).estVaincu()) {
			return false;
		}
		if(!Toolbox.equals(choseEquipee(), ((Personnage) o).choseEquipee())) {
			return false;
		}
		if(estEquipe() != ((Personnage) o).estEquipe()) {
			return false;
		}
		if(versLaDroite() != ((Personnage) o).versLaDroite()) {
			return false;
		}
		if(estGele() != ((Personnage) o).estGele()) {
			return false;
		}
		
		return true;
	}

	/** _________________________________________________________ OBSERVATORS */
	@Override
	public String nom() {
		return nom;
	}

	@Override
	public int force() {
		return force;
	}

	@Override
	public int maxPointsDeVie() {
		return maxPointsDeVie;
	}

	@Override
	public int pointsDeVie() {
		return pointsDeVie;
	}

	@Override
	public boolean estVaincu() {
		return estVaincu;
	}

	@Override
	public Equipable choseEquipee() {
		return choseEquipee;
	}

	@Override
	public boolean estEquipe() {
		return estEquipe;
	}

	@Override
	public int estGele() {
		return estGele;
	}
	
	@Override
	public boolean versLaDroite() {
		return versLaDroite;
	}

	/** ___________________________________________________________ OPERATORS */
	@Override
	public void deposerPointsDeVie(int pv) throws ComposantError {
		pointsDeVie = Math.min(pointsDeVie() + pv, maxPointsDeVie());
	}

	@Override
	public void retirerPointsDeVie(int pv) throws ComposantError {
		pointsDeVie = Math.max(0, pointsDeVie() - pv);
		if(pointsDeVie() == 0) {
			estVaincu = true;
		}
	}

	@Override
	public void ramasser(Equipable e) throws ComposantError {
		e.etreRamasse();
		choseEquipee = e;
		estEquipe = true;
	}

	@Override
	public void jeter() throws ComposantError {
		choseEquipee.etreJete(versLaDroite());
		choseEquipee = null;
		estEquipe = false;
	}

	@Override
	public void deplacer(Position p) throws ComposantError {
		if(p.x() > position().x()) {
			versLaDroite = true;
		}
		else if(p.x() < position().x()) {
			versLaDroite = false;
		}
		position = p;
	}

	@Override
	public void geler(int g) throws ComposantError {
		estGele = g;
		estEquipable = true;
	}

	@Override
	public void degeler() throws ComposantError {
		if(!estPorte()) {
			estGele = Math.max(0, estGele() - 1);
			if(estGele() == 0) {
				estEquipable = false;
			}
		}
	}
}
